package com.blb.utils;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * JDBC工具类
 */
public class JDBCUtils {

    private static Properties properties = new Properties();
    private static HikariDataSource hikariDataSource;

    static {
        try {
            properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
            //1.创建Hikari连接池配置对象
            HikariConfig hikariConfig = new HikariConfig(properties);
            //2.创建Hikari连接池对象
            hikariDataSource = new HikariDataSource(hikariConfig);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return hikariDataSource.getConnection();
    }

    /**
     * 获取及设置执行器
     * @param connection
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public static PreparedStatement prepareStatement(Connection connection, String sql, Object... params) throws SQLException, ClassNotFoundException {
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1, params[i]);
        }
        return preparedStatement;
    }

    /**
     * 获取集合
     * @param connection
     * @param tClass
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    public static <T> List<T> getList(Connection connection,  Class<T> tClass, String sql, Object... params) throws Exception {
        ArrayList<T> list = new ArrayList<>();
        ResultSet resultSet = prepareStatement(connection, sql, params).executeQuery();
        while (resultSet.next()){
            T t = tClass.newInstance();     //User user = new User()
            //元数据对象
            ResultSetMetaData metaData = resultSet.getMetaData();
            //获取结果集的列数
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                //获取列名
                String columnLabel = metaData.getColumnName(i);             //user_name         userName
                //转为驼峰命名
                String fileName = humpConversion(columnLabel);
                //反射获取实体属性对象sss
                Field field = tClass.getDeclaredField(fileName);
                field.setAccessible(true);
                //获取结果集的值
                Object value = resultSet.getObject(columnLabel);
                field.set(t, value);
            }
            list.add(t);
        }
        return list;
    }

    /**
     * 获取单个实体
     * @param connection
     * @param tClass
     * @param sql
     * @param params
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T getOne(Connection connection,  Class<T> tClass, String sql, Object... params) throws Exception {
        List<T> list = getList(connection, tClass, sql, params);
        return list.isEmpty()?null:list.get(0);
    }

    /**
     * 转驼峰命令名
     * user_name_name==>userName
     * @param columnLabel
     * @return
     */
    private static String humpConversion(String columnLabel){
        String[] arr = columnLabel.split("_");
        StringBuffer sb = new StringBuffer(arr[0]);
        for (int i = 1; i < arr.length; i++) {
            sb.append(arr[i].substring(0, 1).toUpperCase());
            sb.append(arr[i].substring(1));
        }
        return sb.toString();
    }

}
